Skip to content

Super-domain RBAC + UnifiedBridge: spec + Tier A starter (D-SDR-1, D-SDR-2)#363

Merged
AdaWorldAPI merged 18 commits into
mainfrom
claude/lance-datafusion-integration-gv0BF
May 13, 2026
Merged

Super-domain RBAC + UnifiedBridge: spec + Tier A starter (D-SDR-1, D-SDR-2)#363
AdaWorldAPI merged 18 commits into
mainfrom
claude/lance-datafusion-integration-gv0BF

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Summary

  • Spec landed: .claude/plans/super-domain-rbac-tenancy-v1.md — 4-level OGIT addressing (meta-anchors → super domain → basin → slot), 6 bytes per row (TenantId u32 + OwlIdentity u16), RBAC + multi-tenant Chinese walls, Foundry-parity enforcement narrative. §1-§19 across 6 commits.
  • Tier A starter shipped in lance-graph-callcenter: UnifiedBridge<B: NamespaceBridge> composing the existing per-namespace ontology bridge (lance-graph-ontology::bridges::*) with the existing RBAC policy (lance-graph-rbac::Policy) and TenantId. Plus SuperDomain layer types + reverse-lookup.
  • Consumer-side wiring in MedCare-rs + smb-office-rs (companion PRs on their respective claude/lance-datafusion-integration-gv0BF branches).

Spec scope (§1-§19)

  • §1-§12 — Core architecture: 4-level hierarchy; per-row TenantId u32 + OwlIdentity u16 = 6 bytes; inline per-family codebook with label + schema + verbs (NOT sidecar); single masked DataFusion predicate enforces tenant + super-domain + role + slot in one vector pass; Foundry-parity enforcement surface.
  • §13 — Refinements: composes onto shipped lance-graph-callcenter::policy::PolicyRewriter chain (RowFilter / ColumnMask / RowEncryption / DifferentialPrivacy / Audit); federation A+B+C all viable (LanceDB transparent encrypted view unblocks C); merkle audit chain via shipped MerkleRoot::from_fingerprint + ClamPath; hard-lock matrix (Healthcare ↔ OSINT + 3 others) with 3 defensive layers; researcher role hardened to anonymized-projection-only.
  • §14 — Harvest + templates: meta-bridge extracted from shipped medcare_bridge.rs + sharepoint_bridge.rs; woa_bridge retrofit; new hubspot_bridge + hiro_bridge templates.
  • §15 — Multi-impl drift detection (preserved as design arc; substantially refined by §16+§17).
  • §16 — Zone 3 drift boundary + two-track migration: pre-prod posture (nothing in production), single 3DES cipher (not chain), MerkleRoot-cleartext-beside-ciphertext (no privileged plaintext access for drift in steady state), MedCare MySQL Struktur reality check (104 tables, all VARCHAR/TEXT/DATETIME, app-layer 3DES not at-rest).
  • §17 — DataFusion SQL inside LanceDB as unified persistence; Arrow Flight SQL replaces custom Protobuf IDL.
  • §18 — Empirical reality check via pygithub REST: LanceProbe (8 components in MedCareV2) IS the drift bridge concept, M1 scaffolded; CRITICAL crypto correction (the "3DES" is 128-bit truncated + ECB-equivalent + zero IV → effectively single DES); migration is Argon2-backfill-on-login, not 3DES→AES-GCM rewrap.
  • §19 — Build invariants (rust 1.94.1 / lance =4.0.0 / lancedb 0.27.2) + ndarray::simd canonical SIMD path (already shipped — just import, no LOC reduction story).

Implementation scope (Tier A starter)

D-SDR-1 — UnifiedBridge (commit f627ef1)

New module crates/lance-graph-callcenter/src/unified_bridge.rs (~210 LOC + 4 tests):

Type Size Role
UnifiedBridge<B: NamespaceBridge> generic Composes ontology bridge + RBAC policy + tenant tag
TenantId(u32) 4 B Multi-tenant Chinese wall tag
AuthError enum Bridge(BridgeError) / Denied / Escalation
// Wiring at the call site:
let bridge = MedcareBridge::from_registry(registry).unwrap();
let policy = Arc::new(smb_policy());
let unified = UnifiedBridge::new(Arc::new(bridge), policy, "accountant", TenantId(1));
let entity = unified.authorize_read("Customer", PrefetchDepth::Detail)?;
  • Cargo.toml: added lance-graph-rbac as path dep (lance-graph-ontology was already there from D-CASCADE-V1-3).
  • Generic over the bridge type → consumers get UnifiedBridge<MedcareBridge> / UnifiedBridge<WoaBridge> without dynamic dispatch.

D-SDR-2 — SuperDomain layer (commit 17987ce)

New module crates/lance-graph-callcenter/src/super_domain.rs (~290 LOC + 7 tests):

Type Size Role
SuperDomain enum 1 B 8 starter activation roots (Healthcare/Science/Genetics/QuantumPhysics/TicketTool/WorkOrderBilling/Osint); 256-slot cap
MetaAnchors ~32 B Foundry ObjectType / OWL upper class / DOLCE marker / Wikidata QID cross-walks
DolceMarker 1 B Endurant / Perdurant / Quality / Abstract
ComplianceRegime 1 B HIPAA / SOX / PCI-DSS / GDPR / OSINT / ITAR-EAR
SuperDomainEntry ~30 B super_domain + basins[] + meta + label + compliance
SUPER_DOMAINS static ~240 B 8 starter entries indexed by variant ord
FAMILY_TO_SUPER_DOMAIN static 256 B basin u8 → SuperDomain reverse lookup

Plus OgitFamily(u8) + OwlIdentity(u16) newtypes added to unified_bridge.rs (Level-2 basin pointer + Level-3 per-row identity; high byte = family, low byte = slot; bitmask predicate helpers).

D-SDR-2 scope: type system + lookup tables. UnifiedBridge::authorize() wiring against the new types lands as D-SDR-5 (4-stage authorize against PolicyRewriter).

Verification

  • cargo clippy -p lance-graph-callcenter --tests --no-deps → 0 errors on new code
  • 11 new unit tests pass (4 for UnifiedBridge, 7 for SuperDomain types)
  • 3 pre-existing "always true" warnings in zone_serialize_check tests are not introduced by this PR

Companion PRs (consumer-side migrations)

  • AdaWorldAPI/MedCare-rs#?medcare-analytics/src/unified_bridge_wiring.rs (constructs UnifiedBridge<MedcareBridge> for HIPAA scope)
  • AdaWorldAPI/smb-office-rs#?smb-bridge/src/unified_bridge_wiring.rs (constructs UnifiedBridge<OgitBridge> for SMB / parameterized namespace)

Both gate behind existing lance-phase2-rbac / auth features respectively. Not breaking for current consumers — adds a new module + re-export; existing column_mask_bridge / auth / rls paths unchanged.

What's NOT in this PR

  • D-SDR-3OgitFamilyTable + FamilyEntry (inline label/schema/verbs per §3.3)
  • D-SDR-4 — Merkle audit chain wiring (AuditEntry with MerkleRoot + ClamPath + super_domain_salt)
  • D-SDR-5 — 4-stage authorize() against PolicyRewriter (the actual super-domain enforcement; wires D-SDR-1..4 together)
  • D-SDR-6..D-SDR-39 — TTL namespaces, consumer crates, compliance certification, federation Phase 2, drift bridge endpoints (D-SDR-35..39 for LanceProbe M5/M6 unblock)
  • RoleGroup + FieldRedactionMask + BitSet256 + hard_lock_partners — deferred to D-SDR-5 since they gate the authorize flow

Test plan

  • cargo build -p lance-graph-callcenter succeeds
  • cargo test -p lance-graph-callcenter unified_bridge — 4 tests pass
  • cargo test -p lance-graph-callcenter super_domain — 7 tests pass
  • cargo clippy -p lance-graph-callcenter --tests --no-deps -- -D warnings clean on new code
  • Companion consumer PRs (MedCare-rs, smb-office-rs) build with lance-phase2-rbac / auth features

File inventory

.claude/plans/super-domain-rbac-tenancy-v1.md       (NEW, ~1300 lines, §1-§19)
.claude/board/INTEGRATION_PLANS.md                  (PREPEND entry + 4 correction lines per APPEND-ONLY governance)
crates/lance-graph-callcenter/Cargo.toml            (+lance-graph-rbac dep, +thiserror)
crates/lance-graph-callcenter/src/lib.rs            (+unified_bridge mod, +super_domain mod, re-exports)
crates/lance-graph-callcenter/src/unified_bridge.rs (NEW, ~360 LOC)
crates/lance-graph-callcenter/src/super_domain.rs   (NEW, ~290 LOC)
Cargo.lock                                          (dep-graph regeneration)

https://claude.ai/code


Generated by Claude Code

AdaWorldAPI and others added 17 commits May 6, 2026 23:59
…ate inventory + anti-patterns + wiring recipes

Authored after a session that walked through ~10 rounds of "is X new?"
→ "no, X exists at Y" before finally building the workspace map. The
patterns here are the cost of that walk, captured so the next session
pays a tax of one read instead of ten rounds.

Five traversal patterns:
- P-1 CRATE-FIRST: read Cargo.toml workspace.members BEFORE proposing
- P-2 REGION-FIRST: name your concept's R-id from soa-dto-fma-map
- P-3 ENTROPY-FIRST: sort ledger by Entropy DESC; highest = highest leverage
- P-4 APPEND-ONLY: board files never edit prior; only append dated sections
- P-5 CLUSTER-AWARE: when fixing one row, check Section B siblings

Crate inventory (canonical at 2026-05-06): ~22 crates listed with
region(s) and what each owns — the universe of "does this exist?".
Five anti-patterns observed in this session (Discovery Loop, Harvest-
from-Stale, Map-Blindness, Single-Name Lookup, Plan-Doc-Without-Code-
Check) with concrete cures.

Equivalence map: ladybug-rs/src/spo modules ↔ lance-graph workspace
locations (e.g. clam_path ≅ cam_pq, nsm_substrate ≅ deepnsm::codebook,
sentence_crystal ≅ holograph::sentence_crystal, DN-tree binding ≅
holograph::{dntree,dn_sparse,navigator}).

Six wiring recipes (CAM-DIST-1 register, PARSER-1 wire, DEEPNSM-NSM-1
collapse, VSA-1 methods, MEMBRANE-GATE-1 done, WATCHER-1 done) — concrete
non-duplicating wirings using only existing primitives.

Pre-work checklist + ledger update protocol restated.

Companion to soa-dto-fma-map.md + ARCHITECTURE_ENTROPY_LEDGER.md.
…PY_LEDGER

Append-only update to the entropy ledger per its own Update Protocol.
Records:

State changes:
- WATCHER-1: Stalled → Wired (sync, std-only) per topology I-2.
  Evidence: PR #337 (commit c1fc1e5). Transport layer correct;
  MVCC bind to Dataset::checkout_latest().version() still pending.
  Entropy 4 → 3.
- POLICY-1 / MEMBRANE-GATE-1: Stalled → Wired on BOTH consumer sides
  via newtype-bridge pattern. SMB side (smb-office-rs#29 — SmbMembraneGate
  over Arc<lance_graph_rbac::Policy>) + medcare side (medcare-rs#98 —
  MedCareMembraneGate over Arc<medcare_rbac::Policy>, with 12+3 agent
  sprint trail at .claude/board/sprint-log/). 4 CRITICAL fixes applied
  during sprint (BMV-Ä §57 Anamnese append-only, receptionist clinical-
  blind safety, StepDomain::Medcare casing + HIPAA values, policy.rs
  test alignment). Entropy 4 → 2 / 3 → 2.
- SPLAT-1: stage advance via PR #336 + #344. 22 splat tests now passing.

New rows:
- CYCLE-ACCUM-1: per-cadence flush gate, distinct from collapse_gate
  per topology I-4. Wired in PR #337 with 11 tests. Entropy 2.
- LADYBUG-EQUIV-1: ladybug-rs ↔ lance-graph equivalence closure.
  Documented mapping (clam_path ≅ cam_pq, nsm_substrate ≅ deepnsm,
  sentence_crystal ≅ holograph, DN-tree binding ≅ holograph::dntree,
  etc.). Verdict: harvest empty. Entropy 1 (clean closure).

Workspace crate inventory expansion: prior models tracked ~5 crates;
canonical inventory is ~22 (lance-graph + lance-graph-contract +
lance-graph-planner + lance-graph-callcenter + lance-graph-rbac +
lance-graph-archetype + lance-graph-catalog + lance-graph-cognitive +
cognitive-shader-driver + deepnsm + holograph + bgz-tensor +
highheelbgz + reader-lm + jc + thinking-engine + neural-debug +
learning + causal-edge + medcare-rs/{medcare-rbac,medcare-realtime,...} +
smb-office-rs/{smb-realtime,...} + q2/cockpit-server).

Cross-references: .claude/patterns.md (NEW, commit cd95da9) — graph-
traversal usability guide. SINGLE_BINARY_TOPOLOGY.md — three-layer
invariants. MEDCARE_POLICY_GAP.md — scoping. CROSS_REPO_PRS.md —
append-only external-repo log. sprint-log/ — 12+3 agent sprint trail.

Open seams: 8 → 5 (3 closed via PR #337 + #29 + #98).

Pre-work checklist for future sessions added — the load-bearing surface
that prevents the discovery-loop cost this session paid (~10 rounds of
"is X new?" → "no, X exists at Y").

[Note: this branch's pre-existing ledger state was stale; this commit
writes [main_content + 2026-05-06 dated append] so the user-side merge
keeps everything from main plus the new section.]
#353); append 2026-05-07 CYCLE-ACCUM-1 + LADYBUG-EQUIV-1 + crate inventory 22→23

Rebases the ledger so it begins with current main's content (commit
a6797ad with all six 2026-05-06/2026-05-07 dated sections from PRs
#345/#346/#347/#348) and then appends a single dated section
"2026-05-07 — CYCLE-ACCUM-1 + LADYBUG-EQUIV-1 introductions + crate
inventory expansion (post-#353)" containing only the unique findings
not already absorbed by those merged PRs:

- CYCLE-ACCUM-1 row introduction (per-cadence flush gate, R2,
  shipped via PR #337, entropy 2)
- LADYBUG-EQUIV-1 row introduction (ladybug-rs ↔ lance-graph
  equivalence map; harvest is empty, entropy 1, full mapping table
  for clam_path, nsm_substrate, sentence_crystal, spo_harvest,
  causal_trajectory, gestalt, nsm_primes, crystal_lm, dn-tree)
- Crate inventory expanded 22 → 23 (sigker added by PR #348)
- Cross-references include PR #109 medcare-rs (?source=lance
  toggle exercising per-request RlsRewriter+ColumnMaskRewriter
  pattern) + PR #353 (palantir-parity-cascade-v2 +
  soa-dto-dependency-ledger)
- Open question flagged: .claude/pattern.md (singular, PR #345)
  vs .claude/patterns.md (plural, this session) filename collision
  awaiting user resolution

State-change blocks for WATCHER-1 / POLICY-1 / MEMBRANE-GATE-1 /
SPLAT-1 are NOT duplicated here — the corresponding 2026-05-06
entries from PR #345/#346 already cover those state changes.
Original branch authoring is preserved at commit 0dd0f56 for
archaeology.
…it had placeholder truncation)

Previous commit 74e2d9e accidentally truncated the file to ~2.5 KB
(just the rubrics header). This commit restores the full 88 KB
rebased ledger: current main content (commit a6797ad with all six
2026-05-06/2026-05-07 dated sections from PRs #345/#346/#347/#348)
+ the unique 2026-05-07 CYCLE-ACCUM-1 + LADYBUG-EQUIV-1 dated section
appended at the end.
…ws + Per-row-context cluster

Append a 2026-05-07 dated section recording the architectural impact
of PR #355 (palantir-cascade, 11 deliverables / 12 agents / 3 waves,
merged 13:40 UTC). Pillar 0 realized end-to-end: OntologyRegistry IS
the SoA, schema IS the DTO + index. O(1) probe: 2554× over SPARQL-
proxy (target ≥ 100× exceeded by 25.5×).

State changes:
- SPO-1: Stalled (entropy 4) → Wired (entropy 2) via SpoBridge::
  promote_to_spo writer. The two SPO stores are tiers, not duplicates.
- TTL-PROBE-5: Aspirational → Wired via AttributeProvenance + Wave-3
  cascade-cols.

New rows (entropy / maturity / Smart-Dumb scored):
- ONTOLOGY-REGISTRY-SOA-1 (E 2, Stage 3, Smart) — Pillar 0
- MUL-THRESHOLD-1 (E 3, Stage 2, Smart) — for_context() carrier
- CASCADE-COLS-1 (E 3, Stage 2, Dumb) — codec cols on MappingRow
- OBJECT-VIEW-1 (E 3, Stage 1, Smart-leaning) — POD foundry primitives
- BUSDTO-BRIDGE-1 (E 2, Stage 2, Smart) — bit-exact encode path
- CERT-OFFICER-1 (E 3, Stage 2) — syn-based Zone-1/2 build-script gate
- CONTEXT-ID-1 (E 3, Stage 3, Smart) — SchemaPtr widened + 14 ns mappings
- DTO-CLASS-CHECK-1 (E 4, Stage 1) — currently 28/28 FAIL until owner
  crates add classification doc comments

New cluster — Per-row-context (members: MUL-THRESHOLD-1, CASCADE-COLS-1,
CONTEXT-ID-1 + ONTOLOGY-REGISTRY-SOA-1 loose-end; cluster entropy 9):
single 200-300 LOC PR landing per-row BindSpace.context_ids drops three
rows entropy 3 → 2, closes lance_cache.rs lossy-replay seam, and
re-wires driver.rs:303-321 to make trust_below_floor live-effect.

Open seams: 5 → 4 + 2 new = 6 active. Highest-leverage cluster shifts
from Board-hygiene to Per-row-context (lower LOC, cross-row unlock).

Total rows tracked: 43 → 53.
… Foundry-parity enforcement)

Locks the 4-level addressing hierarchy (meta-anchors → super domain → OGIT
basin → within-basin slot) with explicit byte-sized DTOs. 6 bytes per row
(4-byte TenantId + 2-byte OwlIdentity) with single masked DataFusion
predicate enforcing tenant + super-domain + role + slot in one vector pass.

Promotes holograph::dntree::WellKnown ordinals to first-class business-named
SuperDomain enum (Healthcare/Science/Genetics/QuantumPhysics/TicketTool/
WorkOrderBilling/OSINT) with cross-walks to Foundry ObjectType / OWL upper
class / DOLCE marker / Wikidata QID. Wires nested role groups within super
domains plus per-tenant Chinese walls (cryptographic isolation via per-tenant
DEK as backstop to predicate filter).

Corrects an earlier sketch that proposed label-vs-metadata as sidecar tables
joined at query time — that was Neo4j-shaped. Right architecture is inline
per-family codebook addressed by the same 16-bit OwlIdentity. No join.

Locks 2-consumer ticket-system constraint: hiro-rs absorbs all 4 OSLC-*
namespaces with off-label fit acceptable (provenance lineage in FamilyEntry);
hubspot-rs is fresh basin (CRM codebook has zero overlap with Hiro IT-ops).

Tier A DTOs (D-SDR-1..5), Tier B TTL namespaces (D-SDR-6..7 on OGIT fork),
Tier C consumer crates (D-SDR-8..9), Tier D compliance + audit (D-SDR-10..11),
Tier E cross-tenant federation (D-SDR-12, Phase 2).

Builds on shipped substrate: SchemaPtr packed u32, OgitBridge +
BridgeFromRegistry, NamespaceRegistry::seed_defaults, DnPath compression
chain (ZeckBF17→Base17→CAM-PQ→scent), HhtlDEntry bit-packed-hierarchy
pattern, lance-graph-contract::cam CAM-PQ codec contract.

Foundry parity narrative: Palantir charges $1M+/yr for ObjectType-level
enforcement; we ship it as a single masked predicate at the super-domain
boundary, sub-microsecond hot path.

INTEGRATION_PLANS.md prepended per APPEND-ONLY governance.
…iter, A+B+C federation, merkle hard-lock, anonymized researcher

Five same-session refinements folded in additively (§1-§12 architecture
unchanged):

(1) Enforcement composes onto shipped lance-graph-callcenter::policy
PolicyRewriter chain + PolicyKind taxonomy (RowFilter / ColumnMask /
RowEncryption / DifferentialPrivacy / Audit). The 4-stage authorize()
maps 1:1 onto PolicyKind variants — no parallel enforcement path.
~30% Tier A LOC reduction.

(2) Cross-tenant federation upgraded: A (PureWall) + B (KAnonymity) +
C (EncryptedViewAggregate) all accepted. Option C lifted from 2027+
R&D track to viable now via LanceDB transparent encrypted views —
the engine scans/filters/aggregates over encrypted columns without
decrypting full rows.

(3) Audit chain integrity built-in via shipped MerkleRoot::from_fingerprint
+ ClamPath from graph/spo/merkle.rs. AuditEntry carries merkle_root +
clam_path + super_domain_salt; HIPAA reviewers detect post-hoc tampering
because the merkle would not validate.

(4) Hard-lock requirement formalized: Healthcare ↔ OSINT (and 3 other
pairs) get 3 layers of cryptographic defense — predicate-time rejection +
per-super-domain merkle salt + super-domain-scoped HKDF key derivation.
Patient history and OSINT cannot be jointly queried under any role; a
leaked row decrypts only with both tenant DEK AND super-domain context.

(5) researcher role hardened to anonymized-projection-only:
PermissionSet::READ only, no WRITE/EXPORT/REDACT_LIFT, k-anonymity floor
(k≥5 default; per-super-domain override for rare-condition Healthcare
research), DP noise auto-injected on aggregates via PolicyKind::
DifferentialPrivacy.

New deliverables: D-SDR-13 (per-SD merkle salt + HKDF), D-SDR-14
(updated AuditEntry + tamper-detect replay), D-SDR-15 (DP for researcher),
D-SDR-16 (EncryptedViewAggregate federation), D-SDR-17 (hard-lock
partner matrix enforcement).

Resolved open questions: audit format choice + cross-tenant federation.
New open questions: hard-lock partner matrix completeness + per-SD DP
epsilon defaults + merkle salt rotation cadence + per-SD k-anonymity
floor overrides.

INTEGRATION_PLANS.md correction line appended per APPEND-ONLY governance.
…ction design arc, Zone 3 boundary, LanceDB+Flight SQL convergence

Four sections appended capturing the post-§13 architectural refinements
from the same session. APPEND-ONLY governance preserved — §1-§13 unchanged.

§14 — Harvest + Templates + Cross-Language Migration
- 3-step rhythm: harvest medcare_bridge + sharepoint_bridge → template
  woa-rs retrofit + new hubspot_bridge + new hiro_bridge → migrate existing
  consumers (MedCare-rs / smb-office-rs retrofit; MedCareV2 reshape per §17)
- Tier F (D-SDR-18 archaeology, D-SDR-19 MetaBridge extract) + Tier G
  (D-SDR-21..23 migrations)
- D-SDR-20 (custom Protobuf IDL) SUPERSEDED by §17.3 — Arrow Flight SQL
  has the wire layer

§15 — Multi-Implementation Drift Detection (initial framing)
- DriftableOutput + DriftReport + MetaBridgeVersion + BridgeImpl DTOs
- 12 cross-language byte-determinism rules (HashMap iter, FP summation,
  string hashing, decimal arithmetic, etc.)
- D-SDR-24 (MySQLAdapterBridge), D-SDR-25 (DriftDetectionBridge),
  D-SDR-26 (determinism test suite)
- Preserved as design arc — substantially refined by §16+§17

§16 — Zone 3 Drift Boundary + Two-Track Migration
- Pre-prod posture corrected: nothing in production, single one-shot
  import not persistent parallelbetrieb infrastructure
- Single 3DES cipher (well-known algorithm), not 3-cipher chain
- Zone 3 placement collapses determinism rules from 12 to ~3
- MerkleRoot-cleartext-beside-ciphertext: drift bridge compares without
  decrypting in steady-state, encryption uses random nonces (no GCM-SIV needed)
- Two-track model: John Doe (billing+tickets in WoA/Hiro databases, no 3DES) +
  3DES PHI (MedCare MySQL clinical columns)
- D-SDR-27 (3DES rewrap one-shot), D-SDR-28 (MerkleRoot beside ciphertext),
  D-SDR-29 (two-track runner), D-SDR-30 (3DES key destroy)
- §16.7 MedCare MySQL Struktur reality check: 104 tables, all VARCHAR/TEXT/
  DATETIME, app-layer 3DES not at-rest, schema purely clinical (billing/tickets
  live in separate WoA/Hiro databases). 38 pf_* tables are Patient
  substructure not 38 entities. Healthcare basin estimate ~30-50 slots used,
  comfortably within 256-slot ceiling.

§17 — DataFusion SQL inside LanceDB as unified persistence + access
- Convergence: MedCare-rs (in-process DataFusion) + MedCareV2 C# (Arrow
  Flight SQL gRPC) → same LanceDB tables via same logical plan layer
- Phase sequencing 0-4: import → dual-write → drift-clean → cutover
- D-SDR-20 RESOLUTION: Arrow Flight SQL replaces custom Protobuf IDL —
  Substrait extension types for OwlIdentity/MerkleRoot/SuperDomain
- Drift bridge bounded to Phase 2-3 window; retires to CI gate after Phase 4
- D-SDR-31 (Flight SQL server), D-SDR-32 (C# Flight SQL client),
  D-SDR-33 (Substrait extension types), D-SDR-34 (Phase-2 dual-write
  coordination)
- Dropped scope: MySQLAdapterBridge, persistent production drift infra,
  multi-trustee key escrow, C-ABI FFI option, custom Protobuf IDL
- §17.7 net architecture summary across §13+§14+§15+§16+§17

§18 deferred pending MCP scope expansion to AdaWorldAPI/MedCare + MedCareV2
for 3DES column inventory + transcoded shape grep. Will fold findings as
follow-up commit when scope lands.

INTEGRATION_PLANS.md second correction line appended per APPEND-ONLY governance.
…/MedCareV2 inspection

Inspected AdaWorldAPI/MedCareV2 + AdaWorldAPI/MedCare-rs@claude/csharp-
handoff-docs-L3DF0 via pygithub REST (token-quote-stripped per cca2a-sprint-
prompt-template guardrail). Major findings refine §15-§17 substantially.

Drift bridge already designed and partially scaffolded:
- MedCareV2/MedCare_2.0/LanceProbe/ contains 8 components mapping nearly 1:1
  to my spec's DTOs (ParityClient → MetaBridge HTTP, ParityWitness →
  DriftDetectionBridge + canonicalization, DriftSink → AuditSink async batch,
  ParityPanel → admin UI, DiagnosisRedactor → FieldRedactionMask).
- M1 complete (scaffolding compiles, throws NotImplementedException);
  M2-M6 pending Rust-side endpoints D-SDR-35..39.
- Coordination spec at MedCare-rs/docs/CSHARP_HANDOFF_PROMPT.md.

MedCareV2 is overlay-only, NOT reshapeable:
- Per docs/PARITY_TOOL_OVERVIEW.md: copy of MedCare + LanceProbe additions.
- Explicit constraint: "do NOT refactor... the diff must be additions only."
- §16.2 framing of MedCareV2 as "partial rewrite, reshapeable freely" CORRECTED.

CRITICAL crypto correction:
- The "3DES" in Crypt.cs:438-451 is broken security, not just outdated.
- 128-bit truncated key (TripleDESCryptoServiceProvider with CryptDeriveKey
  yielding 16 bytes instead of 24) = cryptographically equivalent to single
  DES with 56-bit effective strength (broken since late 1990s).
- Zero IV + ECB-equivalent + non-standard MD5+RC2 KDF + no salt.
- Password source: hardcoded 62-entry Passwort_Crypt[] array
  (Crypt.cs:285-349); NOT user-input-derived.
- Ciphertext format: [1-char index prefix][base64(encrypted bytes)].
- Migration is NOT 3DES→AES-GCM rewrap; it's Argon2-backfill-on-login per
  existing MedCare-rs/docs/AUTH_LEGACY_TRIPLEDES_MIGRATION.md plan.

D-SDR-27 scope reduces:
- Only u_pwd column on praxis_mitarbeiter uses the 3DES path; rest of the
  schema is plaintext (likely no other EncryptMessage call sites).
- Pipeline: carry ciphertext forward as opaque blob; Argon2 backfill happens
  on first successful user login (separate code path).
- Reduced from ~250 LOC + 4 tests to ~80 LOC + 2 tests.
- Removes the AES-GCM rewrap logic entirely (wrong for actual data shape).

Canonicalization rules concretized:
- §15.2 abstract 12-rule cross-language determinism table replaced by
  6 concrete rules from CSHARP_HANDOFF_PROMPT.md lines 93-104:
  geburtsdatum/p_birth (ISO date), werte (F4 InvariantCulture), pf_delete
  (bool null/0→false), db_spez (tinyint→bool), u_pwd (byte-equivalent),
  created_at/d_createdate/updated_at (second-truncated ISO).
- D-SDR-26 test surface drops to 6 named tests.

§17.3 Arrow Flight SQL is aspirational:
- Immediate path is HTTP+JSON over JWT (what LanceProbe already targets).
- Flight SQL convergence is Phase 5+ migration after JSON path is drift-clean.

5 new Rust-side deliverables (D-SDR-35..39) blocking LanceProbe M5/M6:
- D-SDR-35: POST /api/__parity/csharp ingest endpoint
- D-SDR-36: GET /api/__parity dashboard endpoint
- D-SDR-37: _dto_contracts.md stable JSON DTO contracts (blocks M2)
- D-SDR-38: legacy-tripledes-fallback feature flag (blocks M5a)
- D-SDR-39: /api/__parity/telemetry endpoint

Phase sequencing now concrete (replaces §17.2 abstract version):
- Phase 0: M1 done. Phase 1: M2 + D-SDR-31/37. Phase 2: M3+M4 + D-SDR-33.
- Phase 3: M5 + D-SDR-35/36. Phase 3a: M5a + D-SDR-38. Phase 4: M6 + D-SDR-39/30.

Resolved 7 prior open questions; added 3 new ones.

INTEGRATION_PLANS.md third correction line appended per APPEND-ONLY governance.
…onical SIMD path

Locks the build invariants for all D-SDR-* deliverables:

Pinned versions (per PR #275 + Cargo.toml):
- rust 1.94.1 (MSRV; portable_simd patterns ndarray::simd uses)
- lance =4.0.0 (exact pin)
- lancedb 0.27.2

ndarray::simd is the canonical SIMD path:
- All vectorized ops use ndarray::simd from workspace vendored ndarray fork
- Not raw std::simd, not packed_simd, not hand-rolled intrinsics
- One SIMD path, one test surface, one cross-platform contract
- Hot-path ops mapped:
  * OwlIdentity bitmask scans (Cypher MATCH lowering)
  * Batch MerkleRoot computation across rows
  * BitSet256 bitwise ops (role redaction mask)
  * Per-family codebook PQ centroid distance
  * Canonicalization rule application across batch
  * DataFusion predicate vector composition (UnifiedBridge::authorize)
  * ArrowBatchDriftSignal MerkleRoot-of-batch
- Tier A LOC drops ~15-25%: scalar fallback paths collapse to ndarray::simd
  one-liners, no separate code

Mandatory-ndarray promotion (decoupled concurrent workstream):
- User directive: ndarray should be mandatory dep, not optional ndarray-hpc
- Per CLAUDE.md Phase 3 IN PROGRESS already includes the wiring; this
  promotes that to "make ndarray mandatory, retire feature flag"
- NOT blocking any D-SDR-* deliverable
- Tier A may temporarily ship behind #[cfg(feature = "ndarray-hpc")]
  until the promotion lands; gates retire via mechanical find/replace
- Workstream sequencing:
  1. Promote ndarray: feature → mandatory dep (Phase 3 + new directive)
  2. Retire blasgraph/ndarray_bridge.rs standalone fallbacks
  3. Retire #[cfg(feature = "ndarray-hpc")] gates from D-SDR-*

Tradeoff flagged: ndarray::simd couples lance-graph MSRV to ndarray's;
acceptable per workspace policy (ndarray = The Foundation per CLAUDE.md).
Version pinning stricter than rest of workspace, correct for storage layer
+ Flight SQL where minor-version drift causes real bugs.

INTEGRATION_PLANS.md fourth correction line appended per APPEND-ONLY governance.
…ray::simd dispatch is shipped, just import

Same-session correction. I framed §19.2 as "adopt ndarray::simd" with a
"Tier A LOC drops ~15-25%" benefit. Misleading.

The dispatch infrastructure is already shipped in /home/user/ndarray/src/:
- simd.rs (top-level entry, re-exports ops)
- simd_avx2.rs / simd_avx512.rs / simd_neon.rs / simd_amx.rs / simd_wasm.rs
  (per-ISA implementations)
- hpc/simd_caps.rs (LazyLock<SimdCaps> — CPU detect ONCE at first call)
- hpc/simd_dispatch.rs (routes to right per-ISA impl based on detected caps)

Dispatch contract:
1. First ndarray::simd::* call triggers LazyLock CPU detection (CPUID on
   x86, runtime detection on ARM); cached for process lifetime.
2. Subsequent calls route through hpc/simd_dispatch.rs to matching
   simd_{avx512,avx2,neon,amx,wasm}.rs implementation.
3. Polyfill: scalar fallback for unmatched CPUs; correctness-equivalent,
   just slower. Consumers need no cfg-gates.

Already-shipped consumers (per CLAUDE.md "ndarray = The Foundation"):
- bgz17::batch_palette_distance
- lance-graph::graph::blasgraph::* (SIMD Hamming)
- bgz-tensor::cascade::* (SIMD attention)
- thinking-engine::role_tables::*
- lance-graph::graph::neighborhood::* (CLAM scope filter)

Consequence for D-SDR-* deliverables:
- No SIMD code authored — D-SDR-1..3 DTO method bodies just delegate to
  ndarray::simd::* or stay scalar (per-row hot path doesn't need SIMD;
  batch hot path is already handled by ndarray::simd over fingerprint
  columns).
- D-SDR-25 batch MerkleRoot comparison uses ndarray::simd::xor_fold
  (already shipped).
- D-SDR-31 Flight SQL endpoint has no SIMD concerns; underlying DataFusion
  plan execution uses ndarray::simd through lance-graph-planner::physical.

Tier A LOC reduction framing in §19.2 was wrong — LOC was never inflated
by hand-rolled SIMD in the first place. ndarray::simd is invisible at the
call site (which is the point of a dispatch module).

Cfg-gating concern in §19.4 also overstated — other workspace crates
already depend on ndarray unconditionally for SIMD; the
#[cfg(feature = "ndarray-hpc")] gate at lance-graph level is the outlier,
not the norm. Phase 3 promotion aligns lance-graph with what bgz17 /
bgz-tensor / thinking-engine already do.

No spec change needed beyond this clarification. D-SDR-* deliverables
stand as written.
…on-integration-gv0BF

# Conflicts:
#	.claude/board/ARCHITECTURE_ENTROPY_LEDGER.md
#	.claude/patterns.md
…r-domain-rbac-tenancy-v1

Adds the minimal-viable UnifiedBridge per spec §3.9 + §13.1. Composes the
existing per-namespace NamespaceBridge (lance-graph-ontology) with the
existing RBAC Policy (lance-graph-rbac) and a TenantId tag for the
multi-tenant Chinese wall (§3.8). Single entry point consumers import
instead of touching the two crates separately.

Surface (~210 LOC including tests):
- TenantId(u32) newtype with UNKNOWN sentinel
- AuthError enum (Bridge / Denied / Escalation) with predicates
- UnifiedBridge<B: NamespaceBridge> generic struct (Arc<B> + Arc<Policy>
  + actor_role + tenant)
- authorize_read / authorize_write / authorize_act methods that
  resolve-then-evaluate in one call
- 4 unit tests (StubBridge wires the trait without needing TTL hydration)

Wiring at the call site (per medcare-rs / smb-office-rs / future
hiro-rs / hubspot-rs):

    let registry = Arc::new(OntologyRegistry::new_in_memory());
    let bridge = MedcareBridge::from_registry(registry).unwrap();
    let policy = Arc::new(smb_policy());
    let unified = UnifiedBridge::new(
        Arc::new(bridge), policy, "accountant", TenantId(1));
    let entity = unified.authorize_read("Customer", PrefetchDepth::Detail)?;

Cargo.toml: adds lance-graph-rbac as path dep + thiserror for AuthError.
lance-graph-ontology was already a dep (D-CASCADE-V1-3 bridge collapse).

Compiles clean (cargo check + cargo check --tests). Generic over the
bridge type so consumers get UnifiedBridge<MedcareBridge> /
UnifiedBridge<WoaBridge> etc. without dynamic dispatch.

Follow-ups (Tier A continuation, separate commits):
- D-SDR-2: SuperDomain enum + role groups with FieldRedactionMask (§3.4
  + §3.6) — pulls slot-level visibility into the policy chain
- D-SDR-3: OgitFamilyTable inline label+schema+verbs (§3.3) — replaces
  the public_name string lookup with O(1) OwlIdentity resolution
- D-SDR-4: Merkle audit chain (§13.3)
- D-SDR-5: 4-stage authorize() against PolicyRewriter (§13.1)

After SuperDomain + OGIT layers land, the UnifiedBridge surface SHRINKS
(per user direction): public_name string parameter drops in favor of
OwlIdentity, the policy lookup becomes a bitmask predicate against the
slot's RoleGroup mask, and the actor_role resolves to a slot index. The
current ~80 LOC of body code is the wide-API checkpoint; the post-OGIT
shape is ~30 LOC.

Resolves the F2 RBAC wiring deliverable (per main commit 08a3cb9 vision)
at the lance-graph workspace boundary. Consumer-side migration of
medcare-bridge + smb-bridge to import this surface lands next.
…/OwlIdentity DTOs

Extends the UnifiedBridge surface with the Level-1 activation root +
RBAC trust boundary per super-domain-rbac-tenancy-v1 §3.4-§3.7. Adds:

src/super_domain.rs (NEW, ~290 LOC + 7 tests):
- SuperDomain enum (1 byte, 8 starter values: Healthcare / Science /
  Genetics / QuantumPhysics / TicketTool / WorkOrderBilling / Osint;
  256-slot capacity)
- DolceMarker enum (Endurant / Perdurant / Quality / Abstract)
- MetaAnchors struct (Foundry ObjectType / OWL upper class / DOLCE
  marker / Wikidata QID — interop cross-walks)
- ComplianceRegime enum (HIPAA / SOX / PCI-DSS / GDPR / OSINT /
  ITAR-EAR; tags each SuperDomainEntry)
- SuperDomainEntry struct (super_domain + basins[] + meta + label +
  compliance)
- SUPER_DOMAINS static table (8 starter entries, indexed by variant ord)
- FAMILY_TO_SUPER_DOMAIN reverse lookup ([SuperDomain; 256], all
  Unknown until hydration seeds the mapping)
- super_domain_for_family() + super_domain_entry() lookup fns

src/unified_bridge.rs (extended):
- OgitFamily(u8) newtype — Level-2 basin pointer (§3.1)
- OwlIdentity(u16) newtype — Level-3 per-row identity (§3.2). High
  byte = OgitFamily, low byte = within-family slot. Bitmask predicate
  helpers (is_family, is_slot) for Cypher MATCH lowering.

src/lib.rs:
- Re-exports OgitFamily, OwlIdentity, SuperDomain, SuperDomainEntry,
  MetaAnchors, DolceMarker, ComplianceRegime, super_domain_entry,
  super_domain_for_family, SUPER_DOMAINS.

Scope (per spec §8 Tier A D-SDR-2): type system + reverse-lookup
table. The UnifiedBridge::authorize() wiring against the new types
lands as D-SDR-5 (4-stage authorize against PolicyRewriter).

RoleGroup + FieldRedactionMask + BitSet256 + ClearanceLevel +
hard_lock_partners (per §3.6 + §13.4) deferred to D-SDR-5 since they
gate the authorize() flow. PermissionSet (§3.6) deferred — the
existing lance_graph_rbac::PermissionSpec covers the same semantic
slot for the current bridge composition; D-SDR-5 reconciles.

Verification: cargo clippy -p lance-graph-callcenter --tests --no-deps
clean for new code (3 pre-existing "always true" warnings in
zone_serialize_check tests are not introduced here).

Substrate citations:
- Promotes the existing holograph::dntree::WellKnown constants
  (CONCEPTS=0x01, ENTITIES=0x02, NSM primes 0x10-0x4F, ...) to
  first-class business-named activation roots with formal cross-walks.
- Static table sized to ~240 B (8 entries × ~30 B); reverse lookup
  256 B. Negligible runtime overhead.

Per-spec placement note: canonical location for these types is
lance-graph-contract::rbac per Tier A spec; placed alongside
unified_bridge.rs to minimize churn. Mechanical move to contract
when the rbac module is materialized there.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc3696bd90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

depth: PrefetchDepth,
) -> Result<EntityRef, AuthError> {
let entity = self.bridge.entity(public_name)?;
self.evaluate(public_name, Operation::Read { depth })?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Authorize against the resolved entity type

When a bridge public name is an alias, this evaluates RBAC against the alias instead of the resolved ontology type. The existing ontology tests demonstrate WoaBridge can map public name WorkOrder to canonical ogit.WorkOrder:Order; with this code a policy that grants Order access will be denied because Policy::evaluate sees WorkOrder, while alias-specific grants could diverge from the canonical policy. Use the resolved mapping/entity type for the policy check after bridge resolution.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 421e71e. Real bug — thanks for catching it.

Change:

  • All three authorize_* methods now call bridge.row(public_name) (which carries MappingRow.ogit_uri) instead of bridge.entity(public_name) (which only returns the SchemaPtr).
  • New helper canonical_entity_type(row, public_name) extracts row.ogit_uri.name() (the canonical OGIT entity type, e.g. Order for ogit.WorkOrder:Order) and that's what's passed to Policy::evaluate.
  • Falls back to public_name only if the canonical URI somehow lacks a name part (defensive — malformed URI shouldn't break authorization).
  • EntityRef constructed from row.schema_ptr (same pointer the prior path returned).

Cost: bridge.row() calls bridge.entity() internally then enumerates the namespace — O(n) over rows where n ~50 typical. Acceptable on the auth-decision path; the sub-microsecond hot path is the OwlIdentity bitmask predicate one layer down (DataFusion plan-rewrite via PolicyRewriter), which this method gates but does not run on every row.

Two new regression tests in the same file:

  • unified_bridge_evaluates_policy_against_canonical_entity_type — your exact example: caller invokes authorize_read("WorkOrder", ...), registry maps "WorkOrder" → ogit.WorkOrder:Order, policy keyed on "Order" → Allow.
  • unified_bridge_does_not_honor_alias_keyed_policy — inverse: a policy keyed on the alias "WorkOrder" does NOT grant access via the canonical-name path. This is the deliberate decoupling — Foundry-parity-style policies write canonical OGIT names once and any bridge that resolves to them honors the grant.

6/6 unified_bridge tests pass. Module doc on authorize_read calls out the canonical-keying contract so this doesn't regress.


Generated by Claude Code

…dge alias

Codex P2 review on PR #363 caught a real semantic bug: authorize_read /
authorize_write / authorize_act were passing the bridge-side `public_name`
to Policy::evaluate instead of the canonical OGIT entity type that
`bridge.entity()` had just resolved to.

Concrete failure mode (per Codex's example): WoaBridge maps public name
"WorkOrder" → canonical `ogit.WorkOrder:Order`. A policy granting access
to "Order" (canonical) was being evaluated against "WorkOrder" (alias)
and denying access. Conversely, alias-specific grants could diverge
from canonical policy in either direction.

Fix:
- Switch from `bridge.entity(public_name)` to `bridge.row(public_name)`
  in all three authorize_* methods. `row()` returns a `MappingRow`
  carrying the canonical OGIT URI in `row.ogit_uri`; the local-name
  part (`OgitUri::name()`) is the canonical entity type.
- New `canonical_entity_type(row, public_name)` helper extracts the
  canonical name; falls back to `public_name` if the URI somehow
  lacks a name part (defensive — a malformed URI shouldn't break
  authorization).
- EntityRef constructed directly from `row.schema_ptr` (same pointer
  `bridge.entity()` would have returned).

Cost: `bridge.row()` calls `bridge.entity()` internally and then
enumerates the namespace to find the row — O(n) over rows in the
namespace, n ~50 typical. Acceptable on the auth-decision path; the
sub-microsecond hot path is the OwlIdentity bitmask predicate one
layer down (DataFusion plan-rewrite via PolicyRewriter), which this
function gates but does not run on every row.

Two new regression tests:
- `unified_bridge_evaluates_policy_against_canonical_entity_type` —
  policy keyed on "Order" allows the call when caller uses alias
  "WorkOrder"
- `unified_bridge_does_not_honor_alias_keyed_policy` — inverse: a
  policy keyed on the alias "WorkOrder" does NOT grant access through
  the canonical-name evaluation path (proves the decoupling)

Both tests use a real OntologyRegistry seeded with a single
MappingProposal where public_name ("WorkOrder") differs from
ogit_uri.name() ("Order"). 6/6 unified_bridge tests pass.

Architectural note: this means a Policy authored against canonical
OGIT entity types is honored regardless of which bridge / public alias
the caller used. Consumer-facing aliases stay decoupled from policy
authorship — Foundry-parity-style tenant policies write canonical OGIT
names once and any bridge that resolves to them honors the grant.

Module docs (//! header on authorize_read) call this out so future
readers don't re-introduce the bug.

Refs: PR #363 review by chatgpt-codex-connector
@AdaWorldAPI AdaWorldAPI merged commit 00abb94 into main May 13, 2026
5 checks passed
AdaWorldAPI pushed a commit that referenced this pull request May 13, 2026
…+ API-drift + OGIT-axis orthogonality

5 new prepended entries across the three governance files capturing
findings from rapid 2026-05-13 brainstorming:

EPIPHANIES.md (4 new entries, all 2026-05-13):
- THREE-paths-converging (extends the two-paths entry) — Path C =
  `ndarray::simd` canonical SIMD compute substrate per spec §19.2;
  per-row hot path correctly scalar, batch paths should route through
  ndarray::simd (`LazyLock<Tier>` dispatch, gather_u8, xor_fold, etc).
- super-domain-as-subcrate finding — each SuperDomain variant IS its
  own specialised subcrate; Tier C "consumer crate scaffolding" is
  specifically "super-domain subcrate scaffolding"; medcare migration
  is the proof case (3 crates → 1 healthcare re-export).
- API drift mid-flight — medcare-rs failing during migration because
  D-SDR-1..5 grew the UnifiedBridge API in 5 steps over 7 days;
  5-step operational mitigation (SHA pinning + must_use lint +
  deprecation + migration module + CHANGELOG).
- OGIT-axis orthogonality clarification — the §1-§2 "4-level
  hierarchy" framing is partially misleading; SuperDomain × OGIT-basin
  × OWL-leaf × DOLCE-leaf are orthogonal axes, not strictly nested.
  Implications for per-row identity (6 bytes carry OWL only) vs
  column-side metadata (DOLCE / Foundry / Wikidata) and for
  masked-predicate composition (identity-axis predicate separate from
  upper-ontology-axis predicate).
- §16-§19 correction — most was already delivered in PRs #355-#363+
  (sprint-2 + sprint-3 + super-domain spec authoring). Outstanding
  work is composition + implementation of designs that exist; this is
  a morale + scope correction.

IDEAS.md (1 new entry):
- super-domain subcrate scaffolding cascade — 5-PR sequence (MedCare
  finalization → smb-bridge retrofit → woa-rs extraction → hiro-rs
  new → hubspot-rs new) that ships per-super-domain subcrates with
  manifest entries. Depends on Pattern E+F+cognition cascade.

TECH_DEBT.md (3 new TD rows):
- TD-API-DRIFT-MIDFLIGHT-1 (P0): consumer migrations blocked TODAY by
  API drift; needs operational discipline mitigation.
- TD-SUPER-DOMAIN-SUBCRATES-1 (P1): 5 super-domain subcrate slots,
  medcare in-flight, smb in-flight, 3 not started.
- TD-SIMD-CALLCENTER-BATCH-PATHS-1 (P2): batch hot-spots still
  scalar-loop where ndarray::simd is canonical (§19.2).

https://claude.ai/code/session_01PjcbSTd9zdVPkta9qwkVKo
AdaWorldAPI pushed a commit that referenced this pull request May 13, 2026
…cated existing .claude/plans/ corpus

User surfaced 5 prior plans 2026-05-13 evening:
  anatomy-realtime-v1.md (19 KB) — IS W11's FMA spec, pre-existing
  unified-ogit-architecture-v1.md (30 KB, 15 patterns A-O) — supersedes W1
  ogit-g-context-bundle-v1.md — already exists (sprint-3 cited)
  super-domain-rbac-tenancy-v1.md (86 KB, 1387 lines) — canonical PR #363 spec
  compile-time-consumer-binding-v1.md (23 KB) — Pattern E + F sprint-2 plan
Plus prior find: jc-pillars-runtime-wiring-v1.md, lance-graph-rdf-fma-snomed-v1.md,
  2026-05-06-splat-osint-ingestion-v1.md, tetrahedral-epiphany-splat-integration-v1.md,
  foundry-roadmap-unified-smb-medcare-v1.md

Duplication audit: W1 / W4 / W6 / W11 specs partially restate prior
plans; W3 / W7 / W8 / W9 / W10 / W12 added real value. The workers
did not grep .claude/plans/ before drafting.

Same root-cause pattern surfaced THREE times in one session:
  math layer    — one kernel Σ' = J·Σ·Jᵀ, three Jacobians
  substrate     — ndarray::hpc::renderer already exists at 60fps
  plan layer    — 30+ plans already cover the architectural surface

Fix: sprint-5 worker prompt template MUST include a mandatory
read-order section pointing at .claude/plans/ as hard precondition
to spec writing. 12-step read-order added to the EPIPHANIES entry
covering the most-relevant plans by domain.

Sprint-5 priority stack revised: Tier 1 surgical fixes (W10/W8/W9)
stand but reframed as DELTA against super-domain-rbac-tenancy §13;
Tier 2 W4/W6 specs should be REPLACED with delta-against-prior-plan
patches; Tier 3 W11 spec replaced with citation+patches to
anatomy-realtime-v1 + lance-graph-rdf-fma-snomed-v1.
AdaWorldAPI pushed a commit that referenced this pull request May 13, 2026
… sprint, file scope per agent

5 sprints × (12 workers + 2 meta) = 70 agents total. Every W{N} owns
exactly ONE distinct .claude/specs/ file path. Meta agents own
distinct .claude/board/sprint-log-{N}/meta-*-review.md paths.

Sprint 5 (1 wk, substrate close-out): PR-A D-SDR-3/4/5 follow-up + 5
surgical fix PRs (slot widen, bridge-err audit, audit sinks Lance+JSONL,
family hydration, compat shim)

Sprint 6 (2 wk, Tier-2 wiring): 5 super-domain subcrate cascade PRs
(medcare/smb/woa/hiro/hubspot) + thinking-engine wire + manifest modules
+ ractor supervisor — ALL extending prior plans, not redrafting

Sprint 7 (1 wk, FMA convergence): lance-graph-rdf border crate + FMA
two-tier ingest + q2 Cypher wire + heart-click integration test +
Pillar 6 EWA propagation + SIMD callcenter retrofit + SNOMED+RadLex
companions + drug-knowledge crosswalk

Sprint 8 (2 wk, compliance): TTL namespaces + HIPAA/SOX/GDPR cert
surfaces + OSINT LanceProbe + Federation Phase 2 + audit replay CLI +
BAA export + encryption-at-rest gate — addresses D-SDR-6..D-SDR-39
deferred by PR #363

Sprint 9 (1-2 wk, sales asset, parallelizable): holographic q2 UX
(splat shader + highlight column + canonical pose + layer toggle) +
prerender cinematic pipeline (offline tool + player + release artifact)
+ camera storyboard + palette curation + audio cues + recording script

Critical-path total (5+6+7): 4 weeks, ~7100 LOC. Sprints 8/9
independently scheduleable.

Pattern documented end-to-end:
- pre-write SPRINT_LOG.md with roster + mandatory reads
- 12 sonnet workers parallel-spawn in single main-thread call
- meta agents (opus) after workers complete
- main thread aggregates commits + pushes
- governance updates per board-hygiene rule

Worker-prompt template fix from sprint-4 retro baked in: every prompt
includes 12-step .claude/plans/ mandatory-read list as hard precondition.
AdaWorldAPI pushed a commit that referenced this pull request May 28, 2026
…dge alias

Codex P2 review on PR #363 caught a real semantic bug: authorize_read /
authorize_write / authorize_act were passing the bridge-side `public_name`
to Policy::evaluate instead of the canonical OGIT entity type that
`bridge.entity()` had just resolved to.

Concrete failure mode (per Codex's example): WoaBridge maps public name
"WorkOrder" → canonical `ogit.WorkOrder:Order`. A policy granting access
to "Order" (canonical) was being evaluated against "WorkOrder" (alias)
and denying access. Conversely, alias-specific grants could diverge
from canonical policy in either direction.

Fix:
- Switch from `bridge.entity(public_name)` to `bridge.row(public_name)`
  in all three authorize_* methods. `row()` returns a `MappingRow`
  carrying the canonical OGIT URI in `row.ogit_uri`; the local-name
  part (`OgitUri::name()`) is the canonical entity type.
- New `canonical_entity_type(row, public_name)` helper extracts the
  canonical name; falls back to `public_name` if the URI somehow
  lacks a name part (defensive — a malformed URI shouldn't break
  authorization).
- EntityRef constructed directly from `row.schema_ptr` (same pointer
  `bridge.entity()` would have returned).

Cost: `bridge.row()` calls `bridge.entity()` internally and then
enumerates the namespace to find the row — O(n) over rows in the
namespace, n ~50 typical. Acceptable on the auth-decision path; the
sub-microsecond hot path is the OwlIdentity bitmask predicate one
layer down (DataFusion plan-rewrite via PolicyRewriter), which this
function gates but does not run on every row.

Two new regression tests:
- `unified_bridge_evaluates_policy_against_canonical_entity_type` —
  policy keyed on "Order" allows the call when caller uses alias
  "WorkOrder"
- `unified_bridge_does_not_honor_alias_keyed_policy` — inverse: a
  policy keyed on the alias "WorkOrder" does NOT grant access through
  the canonical-name evaluation path (proves the decoupling)

Both tests use a real OntologyRegistry seeded with a single
MappingProposal where public_name ("WorkOrder") differs from
ogit_uri.name() ("Order"). 6/6 unified_bridge tests pass.

Architectural note: this means a Policy authored against canonical
OGIT entity types is honored regardless of which bridge / public alias
the caller used. Consumer-facing aliases stay decoupled from policy
authorship — Foundry-parity-style tenant policies write canonical OGIT
names once and any bridge that resolves to them honors the grant.

Module docs (//! header on authorize_read) call this out so future
readers don't re-introduce the bug.

Refs: PR #363 review by chatgpt-codex-connector
AdaWorldAPI added a commit that referenced this pull request May 28, 2026
…gration-gv0BF

Super-domain RBAC + UnifiedBridge: spec + Tier A starter (D-SDR-1, D-SDR-2)
AdaWorldAPI pushed a commit that referenced this pull request May 28, 2026
…cated existing .claude/plans/ corpus

User surfaced 5 prior plans 2026-05-13 evening:
  anatomy-realtime-v1.md (19 KB) — IS W11's FMA spec, pre-existing
  unified-ogit-architecture-v1.md (30 KB, 15 patterns A-O) — supersedes W1
  ogit-g-context-bundle-v1.md — already exists (sprint-3 cited)
  super-domain-rbac-tenancy-v1.md (86 KB, 1387 lines) — canonical PR #363 spec
  compile-time-consumer-binding-v1.md (23 KB) — Pattern E + F sprint-2 plan
Plus prior find: jc-pillars-runtime-wiring-v1.md, lance-graph-rdf-fma-snomed-v1.md,
  2026-05-06-splat-osint-ingestion-v1.md, tetrahedral-epiphany-splat-integration-v1.md,
  foundry-roadmap-unified-smb-medcare-v1.md

Duplication audit: W1 / W4 / W6 / W11 specs partially restate prior
plans; W3 / W7 / W8 / W9 / W10 / W12 added real value. The workers
did not grep .claude/plans/ before drafting.

Same root-cause pattern surfaced THREE times in one session:
  math layer    — one kernel Σ' = J·Σ·Jᵀ, three Jacobians
  substrate     — ndarray::hpc::renderer already exists at 60fps
  plan layer    — 30+ plans already cover the architectural surface

Fix: sprint-5 worker prompt template MUST include a mandatory
read-order section pointing at .claude/plans/ as hard precondition
to spec writing. 12-step read-order added to the EPIPHANIES entry
covering the most-relevant plans by domain.

Sprint-5 priority stack revised: Tier 1 surgical fixes (W10/W8/W9)
stand but reframed as DELTA against super-domain-rbac-tenancy §13;
Tier 2 W4/W6 specs should be REPLACED with delta-against-prior-plan
patches; Tier 3 W11 spec replaced with citation+patches to
anatomy-realtime-v1 + lance-graph-rdf-fma-snomed-v1.
AdaWorldAPI pushed a commit that referenced this pull request May 28, 2026
… sprint, file scope per agent

5 sprints × (12 workers + 2 meta) = 70 agents total. Every W{N} owns
exactly ONE distinct .claude/specs/ file path. Meta agents own
distinct .claude/board/sprint-log-{N}/meta-*-review.md paths.

Sprint 5 (1 wk, substrate close-out): PR-A D-SDR-3/4/5 follow-up + 5
surgical fix PRs (slot widen, bridge-err audit, audit sinks Lance+JSONL,
family hydration, compat shim)

Sprint 6 (2 wk, Tier-2 wiring): 5 super-domain subcrate cascade PRs
(medcare/smb/woa/hiro/hubspot) + thinking-engine wire + manifest modules
+ ractor supervisor — ALL extending prior plans, not redrafting

Sprint 7 (1 wk, FMA convergence): lance-graph-rdf border crate + FMA
two-tier ingest + q2 Cypher wire + heart-click integration test +
Pillar 6 EWA propagation + SIMD callcenter retrofit + SNOMED+RadLex
companions + drug-knowledge crosswalk

Sprint 8 (2 wk, compliance): TTL namespaces + HIPAA/SOX/GDPR cert
surfaces + OSINT LanceProbe + Federation Phase 2 + audit replay CLI +
BAA export + encryption-at-rest gate — addresses D-SDR-6..D-SDR-39
deferred by PR #363

Sprint 9 (1-2 wk, sales asset, parallelizable): holographic q2 UX
(splat shader + highlight column + canonical pose + layer toggle) +
prerender cinematic pipeline (offline tool + player + release artifact)
+ camera storyboard + palette curation + audio cues + recording script

Critical-path total (5+6+7): 4 weeks, ~7100 LOC. Sprints 8/9
independently scheduleable.

Pattern documented end-to-end:
- pre-write SPRINT_LOG.md with roster + mandatory reads
- 12 sonnet workers parallel-spawn in single main-thread call
- meta agents (opus) after workers complete
- main thread aggregates commits + pushes
- governance updates per board-hygiene rule

Worker-prompt template fix from sprint-4 retro baked in: every prompt
includes 12-step .claude/plans/ mandatory-read list as hard precondition.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants